package com.smm.web.mtower.handler;


import com.smm.web.mtower.bo.EventBO;
import com.smm.web.mtower.domain.TagAlamEvent;
import org.apache.log4j.Logger;
import org.apache.mina.core.buffer.IoBuffer;
import org.apache.mina.core.service.IoHandlerAdapter;
import org.apache.mina.core.session.IdleStatus;
import org.apache.mina.core.session.IoSession;

import javax.annotation.Resource;
import java.net.SocketAddress;

/**
 * Created by zhenghao on 2016/7/21.
 *
 */
public class RfidHandler extends IoHandlerAdapter {


    private Logger logger= Logger.getLogger(this.getClass());

    @Resource
    private EventBO eventBO;



    @Override
    public void sessionCreated(IoSession session) throws Exception {
        System.out.println("Session created...");
        SocketAddress remoteAddress = session.getRemoteAddress();
        System.out.println(remoteAddress);
    }

    @Override
    public void sessionOpened(IoSession session) throws Exception {
        System.out.println("Session Opened...");
        SocketAddress remoteAddress = session.getRemoteAddress();
        System.out.println(remoteAddress);
    }

    @Override
    public void sessionClosed(IoSession session) throws Exception {
        System.out.println("Session closed...");
    }

    @Override
    public void messageReceived(IoSession session, Object message) throws Exception {

        IoBuffer buffer = (IoBuffer) message;

        //解析数据
        TageInfo tageInfo = decode(buffer.array());

        //回复确认信息
        rebackMsg(session,tageInfo.getmCode());

        //处理标签信息
        disposeTaginfo(tageInfo);

    }

    private void disposeTaginfo(TageInfo tageInfo) throws Exception {

        boolean isAlam = tageInfo.getIsAlam().equals("01");
        String rfidCode = tageInfo.getCardNo();

        try{

            //判断是是标签震动，如果不是震动事件，不做任何处理
            if(!isAlam) return;

            //处理报警事件
            eventBO.disposeAlamEvent(new TagAlamEvent(rfidCode));

        }catch (Exception e){

            e.printStackTrace();

            logger.error(e);
        }

    }

    private void rebackMsg(IoSession session, String mCode) {

        //将字符串转换为16进制
        byte[] bs= hexStringToBytes(mCode);

        byte [] sendBytes = { 0x55, bs[0], bs[1], (byte) 0xa5, 0x01, 0x01, 0x55 };

        //计算补码
        int num = 0x1 + ~(0x01 + 0xa5 + 0x01);

        //补码赋值给数组
        sendBytes[5] = (byte) num;

        //由于是 udp 模式，这里message必须为IoBuffer类型
        session.write(IoBuffer.wrap(sendBytes));
    }


    //字符串转换为16进制数组
    private byte[] hexStringToBytes(String hexString) {
        if (hexString == null || hexString.equals("")) {
            return null;
        }
        hexString = hexString.toUpperCase();
        int length = hexString.length() / 2;
        char[] hexChars = hexString.toCharArray();
        byte[] d = new byte[length];
        for (int i = 0; i < length; i++) {
            int pos = i * 2;
            d[i] = (byte) (charToByte(hexChars[pos]) << 4 | charToByte(hexChars[pos + 1]));
        }
        return d;
    }

    private byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }


    private TageInfo decode(byte[] bytes) {

        StringBuilder msg = new StringBuilder("");

        //全部输出
        for(byte b:bytes){

            msg.append(getByteToString(b)).append(" ");

        }

        logger.info("---tag recive msg:" + msg.toString());


        //读卡器编号
        String mCode= getByteToString(bytes[1]) + getByteToString(bytes[2]);

        //标签震动标志
        String isAlam =getByteToString(bytes[8]).equals("00")?"01":"00";

        //标签卡号
        String cardNo ="";

        //读取卡号
        for(int i=9;i<17;i++){

            cardNo = cardNo + getByteToString(bytes[i]);
        }

        return new TageInfo(mCode,isAlam,cardNo);
    }


    private String getByteToString(byte b) {

        String str=  Integer.toHexString(b & 0xff).toUpperCase();

        //小于2位补零
        if(!str.trim().equals("") && str.length()<2) str = "0"+str;

        return str;
    }


    @Override
    public void messageSent(IoSession session, Object message) throws Exception {
        super.messageSent(session, message);

    }

    @Override
    public void sessionIdle(IoSession session, IdleStatus status) throws Exception {
        super.sessionIdle(session, status);
    }
}
